package com.ruoyi.campus.controller;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.ruoyi.campus.domain.UserExtend;
import com.ruoyi.campus.dto.MiniProgramAuthRequest;
import com.ruoyi.campus.dto.MiniProgramAuthResponse;
import com.ruoyi.campus.dto.MiniProgramLoginRequest;
import com.ruoyi.campus.service.IUserExtendService;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.web.service.SysLoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

/**
 * 小程序API控制器
 * 
 * @author campus-alarm
 * @date 2024-01-01
 */
@RestController
@RequestMapping("/miniprogram")
public class MiniProgramController extends BaseController {

    @Autowired
    private WxMaService wxMaService;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private IUserExtendService userExtendService;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private SysLoginService loginService;

    /**
     * 小程序用户名/手机号密码登录
     */
    @Anonymous
    @PostMapping("/auth/passwordLogin")
    public AjaxResult passwordLogin(@Validated @RequestBody MiniProgramLoginRequest request) {
        try {
            String account = request.getAccount().trim();
            String password = request.getPassword();
            String loginType = request.getLoginType();
            
            logger.info("开始密码登录，账号：{}，登录类型：{}", account, loginType);
            
            // 根据登录类型查找用户
            SysUser sysUser = null;
            UserExtend userExtend = null;
            
            try {
                if ("username".equals(loginType)) {
                    // 用户名登录
                    logger.info("尝试根据用户名查找用户：{}", account);
                    sysUser = userService.selectUserByUserName(account);
                    logger.info("根据用户名查找用户结果：{}", sysUser != null ? sysUser.getUserId() : "null");
                } else if ("phone".equals(loginType)) {
                    // 手机号登录 - 通过查询列表方式实现
                    logger.info("尝试根据手机号查找用户：{}", account);
                    SysUser queryUser = new SysUser();
                    queryUser.setPhonenumber(account);
                    java.util.List<SysUser> userList = userService.selectUserList(queryUser);
                    logger.info("根据手机号查找用户结果数量：{}", userList.size());
                    if (!userList.isEmpty()) {
                        sysUser = userList.get(0);
                        logger.info("选择第一个用户：{}", sysUser.getUserId());
                    }
                }
            } catch (Exception e) {
                logger.error("查找用户时发生异常", e);
                return AjaxResult.error("查找用户失败：" + e.getMessage());
            }
            
            if (sysUser == null) {
                return AjaxResult.error("用户不存在");
            }
            
            // 验证密码
            logger.info("开始验证密码，用户ID：{}，密码格式：{}", 
                       sysUser.getUserId(), 
                       sysUser.getPassword() != null && sysUser.getPassword().startsWith("$2a$") ? "BCrypt" : "明文");
            
            if (!SecurityUtils.matchesPassword(password, sysUser.getPassword())) {
                logger.warn("密码验证失败，用户ID：{}", sysUser.getUserId());
                return AjaxResult.error("密码错误");
            }
            
            logger.info("密码验证成功，用户ID：{}", sysUser.getUserId());
            
            // 检查用户状态
            if ("1".equals(sysUser.getStatus())) {
                return AjaxResult.error("用户已被停用，请联系管理员");
            }
            
            // 获取用户扩展信息
            try {
                logger.info("尝试获取用户扩展信息，用户ID：{}", sysUser.getUserId());
                userExtend = userExtendService.selectUserExtendByUserId(sysUser.getUserId());
                logger.info("获取用户扩展信息结果：{}", userExtend != null ? "成功" : "null");
            } catch (Exception e) {
                logger.error("获取用户扩展信息时发生异常", e);
                return AjaxResult.error("获取用户扩展信息失败：" + e.getMessage());
            }
            
            // 创建LoginUser对象
            LoginUser loginUser = new LoginUser(sysUser.getUserId(), sysUser.getDeptId(), sysUser, null);
            
            // 生成JWT Token
            String token = tokenService.createToken(loginUser);
            
            // 构建响应
            MiniProgramAuthResponse response = new MiniProgramAuthResponse();
            response.setAccessToken(token);
            response.setExpiresIn(7200L); // 2小时过期
            response.setUserId(sysUser.getUserId());
            response.setNickName(sysUser.getNickName());
            response.setAvatarUrl(sysUser.getAvatar());
            
            // 生成WebSocket客户端ID
            response.setClientId("client_" + sysUser.getUserId() + "_" + System.currentTimeMillis());
            
            if (userExtend != null) {
                response.setUserType(userExtend.getUserType());
                response.setIsBound(userExtend.getSchoolId() != null);
                response.setSchoolId(userExtend.getSchoolId());
                response.setClassId(userExtend.getClassId());
                
                // 设置用户类型描述
                switch (userExtend.getUserType()) {
                    case 1:
                        response.setUserTypeDesc("学生");
                        break;
                    case 2:
                        response.setUserTypeDesc("教师");
                        break;
                    case 3:
                        response.setUserTypeDesc("家长");
                        break;
                    case 4:
                        response.setUserTypeDesc("学校管理员");
                        break;
                    default:
                        response.setUserTypeDesc("用户");
                }
            } else {
                response.setUserType(0);
                response.setIsBound(false);
                response.setUserTypeDesc("未设置");
            }
            
            return AjaxResult.success("登录成功", response);
            
        } catch (Exception e) {
            logger.error("账号密码登录失败", e);
            return AjaxResult.error("登录失败：" + e.getMessage());
        }
    }

    /**
     * 小程序微信登录认证
     */
    @Anonymous
    @PostMapping("/auth/login")
    public AjaxResult login(@Validated @RequestBody MiniProgramAuthRequest request) {
        try {
            // 调用微信接口获取session信息
            WxMaJscode2SessionResult sessionInfo = wxMaService.getUserService().getSessionInfo(request.getCode());
            String openid = sessionInfo.getOpenid();
            String unionid = sessionInfo.getUnionid();

            // 查找或创建用户
            UserExtend userExtend = userExtendService.selectUserExtendByOpenid(openid);
            SysUser sysUser;

            if (userExtend == null) {
                // 新用户，创建账号
                sysUser = createNewUser(request, openid, unionid);
                userExtend = createUserExtend(sysUser.getUserId(), request, openid, unionid);
            } else {
                // 已有用户，更新信息
                sysUser = userService.selectUserById(userExtend.getUserId());
                updateUserInfo(sysUser, userExtend, request);
            }

            // 创建LoginUser对象
            LoginUser loginUser = new LoginUser(sysUser.getUserId(), sysUser.getDeptId(), sysUser, null);
            
            // 生成JWT Token
            String token = tokenService.createToken(loginUser);

            // 构建响应
            MiniProgramAuthResponse response = new MiniProgramAuthResponse();
            response.setAccessToken(token);
            response.setExpiresIn(7200L); // 2小时过期
            response.setUserId(sysUser.getUserId());
            response.setNickName(sysUser.getNickName());
            response.setAvatarUrl(sysUser.getAvatar());
            
            // 生成WebSocket客户端ID
            response.setClientId("client_" + sysUser.getUserId() + "_" + System.currentTimeMillis());
            
            response.setUserType(userExtend.getUserType());
            response.setIsBound(userExtend.getUserType() != null);
            response.setSchoolId(userExtend.getSchoolId());
            response.setClassId(userExtend.getClassId());

            return AjaxResult.success(response);

        } catch (Exception e) {
            logger.error("小程序登录失败", e);
            return AjaxResult.error("登录失败：" + e.getMessage());
        }
    }

    /**
     * 获取用户信息
     */
    @GetMapping("/user/info")
    public AjaxResult getUserInfo() {
        Long userId = SecurityUtils.getUserId();
        SysUser user = userService.selectUserById(userId);
        UserExtend userExtend = userExtendService.selectUserExtendByUserId(userId);

        Map<String, Object> userInfo = new HashMap<>();
        userInfo.put("userId", user.getUserId());
        userInfo.put("userName", user.getUserName());
        userInfo.put("nickName", user.getNickName());
        userInfo.put("email", user.getEmail());
        userInfo.put("phonenumber", user.getPhonenumber());
        userInfo.put("avatar", user.getAvatar());
        userInfo.put("userType", userExtend != null ? userExtend.getUserType() : null);
        userInfo.put("schoolId", userExtend != null ? userExtend.getSchoolId() : null);
        userInfo.put("classId", userExtend != null ? userExtend.getClassId() : null);
        userInfo.put("studentNumber", userExtend != null ? userExtend.getStudentNumber() : null);
        userInfo.put("teacherNumber", userExtend != null ? userExtend.getTeacherNumber() : null);

        return AjaxResult.success(userInfo);
    }

    /**
     * 更新用户信息
     */
    @PutMapping("/user/update")
    @Log(title = "更新用户信息", businessType = BusinessType.UPDATE)
    public AjaxResult updateUserInfo(@RequestBody Map<String, Object> userInfo) {
        Long userId = SecurityUtils.getUserId();
        
        try {
            SysUser user = userService.selectUserById(userId);
            if (userInfo.containsKey("nickName")) {
                user.setNickName((String) userInfo.get("nickName"));
            }
            if (userInfo.containsKey("email")) {
                user.setEmail((String) userInfo.get("email"));
            }
            if (userInfo.containsKey("phonenumber")) {
                user.setPhonenumber((String) userInfo.get("phonenumber"));
            }
            userService.updateUser(user);

            return AjaxResult.success();
        } catch (Exception e) {
            logger.error("更新用户信息失败", e);
            return AjaxResult.error("更新失败：" + e.getMessage());
        }
    }

    /**
     * 绑定身份信息
     */
    @PostMapping("/user/bind")
    @Log(title = "绑定身份信息", businessType = BusinessType.UPDATE)
    public AjaxResult bindUserInfo(@RequestBody Map<String, Object> bindInfo) {
        Long userId = SecurityUtils.getUserId();
        
        try {
            UserExtend userExtend = userExtendService.selectUserExtendByUserId(userId);
            if (userExtend == null) {
                return AjaxResult.error("用户扩展信息不存在");
            }

            // 更新身份信息
            if (bindInfo.containsKey("userType")) {
                userExtend.setUserType((Integer) bindInfo.get("userType"));
            }
            if (bindInfo.containsKey("schoolId")) {
                userExtend.setSchoolId(Long.valueOf(bindInfo.get("schoolId").toString()));
            }
            if (bindInfo.containsKey("classId")) {
                userExtend.setClassId(Long.valueOf(bindInfo.get("classId").toString()));
            }
            if (bindInfo.containsKey("studentNumber")) {
                userExtend.setStudentNumber((String) bindInfo.get("studentNumber"));
            }
            if (bindInfo.containsKey("teacherNumber")) {
                userExtend.setTeacherNumber((String) bindInfo.get("teacherNumber"));
            }

            userExtendService.updateUserExtend(userExtend);
            return AjaxResult.success();

        } catch (Exception e) {
            logger.error("绑定身份信息失败", e);
            return AjaxResult.error("绑定失败：" + e.getMessage());
        }
    }

    /**
     * 创建新用户
     */
    private SysUser createNewUser(MiniProgramAuthRequest request, String openid, String unionid) {
        SysUser user = new SysUser();
        user.setUserName("wx_" + openid.substring(0, 8));
        user.setNickName(request.getNickName());
        user.setAvatar(request.getAvatarUrl());
        user.setStatus("0"); // 正常状态
        user.setCreateBy("miniprogram");
        
        userService.insertUser(user);
        return user;
    }

    /**
     * 创建用户扩展信息
     */
    private UserExtend createUserExtend(Long userId, MiniProgramAuthRequest request, String openid, String unionid) {
        UserExtend userExtend = new UserExtend();
        userExtend.setUserId(userId);
        userExtend.setWechatOpenid(openid);
        userExtend.setWechatUnionid(unionid);
        userExtend.setGender(request.getGender());
        userExtend.setCreateBy("miniprogram");
        
        userExtendService.insertUserExtend(userExtend);
        return userExtend;
    }

    /**
     * 更新用户信息
     */
    private void updateUserInfo(SysUser user, UserExtend userExtend, MiniProgramAuthRequest request) {
        // 更新基本用户信息
        if (request.getNickName() != null) {
            user.setNickName(request.getNickName());
        }
        if (request.getAvatarUrl() != null) {
            user.setAvatar(request.getAvatarUrl());
        }
        userService.updateUser(user);

        // 更新扩展信息
        if (request.getGender() != null) {
            userExtend.setGender(request.getGender());
        }
        userExtendService.updateUserExtend(userExtend);
    }
} 